package ru.usu.gv.utils.imports;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import ru.usu.gv.uicomponents.UIEdge;
import ru.usu.gv.uicomponents.UIGraph;
import ru.usu.gv.uicomponents.UIVertex;
import ru.usu.gv.utils.Pair;
import ru.usu.gv.utils.RandomUtilities;
import ru.usu.gv.utils.XmlUtil;

import java.awt.Color;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 @author Sergey Pupyrev 
 */
public class DynamicGraphImporter implements IGraphXmlConstants
{
	private static final double Z_SEPARATION = 0.5;

	public static UIGraph loadGraph(String path) throws XmlParseException
	{
		try
		{
			System.out.print("Start importing graph (" + path + ")...");

			Node graphRootElement = GraphImporter.readRootElement(path, "dynamicgraph");

			String id = XmlUtil.readStringAttribute(graphRootElement, GRAPH_ID);
			UIGraph graph = new UIGraph(id);

			NodeList graphs = XmlUtil.getChildsByTagName(graphRootElement, "graph");
			double z = -(graphs.getLength() - 1.0) * Z_SEPARATION / 2.0;
			for (int i = 0; i < graphs.getLength(); i++)
			{
				Set<String> vertexes = importNodes(graphs.item(i));
				Set<Pair<String, String>> edges = importEdges(graphs.item(i));

				addElements(graph, vertexes, edges, z);
				z += Z_SEPARATION;
			}

			System.out.println("ok");
			return graph;
		}
		catch (XmlParseException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new XmlParseException(e);
		}
	}

	private static Set<String> importNodes(Node node) throws Exception
	{
		Set<String> ids = new HashSet();
		NodeList nodeList = XmlUtil.getChildsByTagName(node, VERTEX_NODE);
		int count = nodeList.getLength();
		for (int i = 0; i < count; i++)
		{
			String id = XmlUtil.readStringAttribute(nodeList.item(i), VERTEX_ID);
			ids.add(id);
		}

		return ids;
	}

	private static Set<Pair<String, String>> importEdges(Node node) throws Exception, XmlParseException
	{
		Set<Pair<String, String>> ids = new HashSet();
		NodeList nodeList = XmlUtil.getChildsByTagName(node, EDGE_NODE);
		int edgeCount = nodeList.getLength();
		for (int i = 0; i < edgeCount; i++)
		{
			Node eNode = nodeList.item(i);
			String begin, end;
			begin = XmlUtil.readStringAttribute(eNode, EDGE_BEGIN);
			end = XmlUtil.readStringAttribute(eNode, EDGE_END);

			ids.add(new Pair(begin, end));
		}

		return ids;
	}

	private static void addElements(UIGraph graph, Set<String> vertexes, Set<Pair<String, String>> edges, double z)
	{
		Map<String, UIVertex> prevVertexes = new HashMap();
		for (int i = 0; i < graph.getVertexes().size(); i++)
		{
			UIVertex v = graph.getVertex(i);
			if (v.getPosition().z == z - Z_SEPARATION)
			{
				prevVertexes.put(v.getLabel(), v);
			}
		}

		Map<String, UIVertex> curVertexes = new HashMap();
		for (String s : vertexes)
		{
			UIVertex v = new UIVertex(RandomUtilities.generateRandomPoint());
			v.getPosition().z = z;
			v.setLabel(s);
			graph.addVertex(v);
			curVertexes.put(s, v);
		}

		for (Pair<String, String> pr : edges)
		{
			UIVertex v = curVertexes.get(pr.getFirst());
			UIVertex u = curVertexes.get(pr.getSecond());

			UIEdge edge = new UIEdge(v, u);
			graph.addEdge(edge);
		}

		for (String s : vertexes)
		{
			UIVertex v = curVertexes.get(s);
			if (prevVertexes.containsKey(s))
			{
				UIVertex u = prevVertexes.get(s);
				UIEdge edge = new UIEdge(v, u);
				edge.getViewItem().setColor(Color.GREEN);
				graph.addEdge(edge);
			}
		}

	}

}
